// function power(x) {
//     var sum = 1;
//     for (let i = 0; i < x; i++) {
//         sum *= 2;
//     }
//     return sum;
// }

// function factorial(x) {
//     var sum = 1;
//     for (let i = 1; i <= x; i++) {
//         sum *= i;
//     }
//     return sum;
// }

// for (let i = 0; i < 10; i ++) {
//     console.log(i, power(i), factorial(i));
// }
// console.log(power(200))
// console.log(factorial(20)/(factorial(5)*factorial(15)))
// console.log(factorial(200)/(factorial(100)*factorial(100)))

// for (let i = 0; i < 200; i += 2) {
//     var p = power(i-4);
//     var c = factorial(i)/(factorial(i/2)*factorial(i/2));
//     // console.log(i, p, c)
//     if (p >= c) {
//         console.log(i,p,c);
//     } else {
//         // return;
//     }
// }

/**
 * 压缩算法详解
 */
// var srcStr = "fdaslkadfkaslkfsjdfjkdsafljlsdaf打首发的说法";
const fs = require("fs");
var srcStr = fs.readFileSync("./三国志.txt").toString();
var srcStrArr = srcStr.split("");
var srcStrDic = {};
var scoreTreeDic = {};
srcStrArr.forEach(function (element) {
    if (srcStrDic[element]) {
        srcStrDic[element] += 1;
    } else {
        srcStrDic[element] = 1;
    }
}, this);
console.log(srcStrDic);
for (var key in srcStrDic) {
    if (srcStrDic.hasOwnProperty(key)) {
        var times = srcStrDic[key];
        if (scoreTreeDic[times]) {
            scoreTreeDic[times].push(key);
        } else {
            scoreTreeDic[times] = [key];
        }
    }
}
function scoreTreeFunc(scoreTreeDic) {

    var lover, loverTimes;
    var end = {};
    var a = 0;
    while (JSON.stringify(scoreTreeDic) != JSON.stringify({})) {
        for (var times in scoreTreeDic) {
            if (scoreTreeDic.hasOwnProperty(times)) {
                var keys = scoreTreeDic[times];
                keys.forEach(function (key) {
                    if (!lover) {
                        lover = key;
                    } else {
                        var sumTimes = parseInt(loverTimes ? loverTimes : times) + parseInt(times);
                        if (scoreTreeDic[sumTimes]) {
                            scoreTreeDic[sumTimes].push({ 0: lover, 1: key });
                        } else {
                            scoreTreeDic[sumTimes] = [{ 0: lover, 1: key }];
                        }
                        lover = 0;
                    }
                    // console.log("------------------------------------");
                    // console.log(scoreTreeDic);
                    end = scoreTreeDic[times];
                    delete scoreTreeDic[times];
                }, this);
                loverTimes = times;
            }
            break;// 这个是精髓，每次都重新 开始拿最小的开始算
        }
    }
    return end;
}
// console.log(scoreTreeFunc(scoreTreeDic));
var final = scoreTreeFunc(scoreTreeDic)[0];
var finalDescriptTreeDic = {};
function descriptTree(srcDic, keyBefore) {
    for (var key in srcDic) {
        if (srcDic.hasOwnProperty(key)) {
            var element = srcDic[key];
            if (typeof (element) !== 'string') {
                descriptTree(element, keyBefore + "" + key);
            } else {
                finalDescriptTreeDic[keyBefore + "" + key] = element;
            }
        }
    }
}
descriptTree(final, "");
console.log(finalDescriptTreeDic);
keyFinalDescriptTreeDic = {};
var b = 0;
// 4900 字
var bDic = {"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0};
for (var key in finalDescriptTreeDic) {
    if (finalDescriptTreeDic.hasOwnProperty(key)) {
        var element = finalDescriptTreeDic[key];
        b++;
        bDic[key.length] += 1;
        keyFinalDescriptTreeDic[element] = key;
    }
}
var a = 0;
// 854358 字
srcStrArr.forEach(function (element) {
    a++;
}, this)
console.log(a, b)

var finalStr = "";
srcStrArr.forEach(function (word) {
    finalStr += keyFinalDescriptTreeDic[word];
}, this);
// { '100': 'a',
//   '101': 's',
//   '111': 'f',
//   '1101': 'j',
//   '11000': '说',
//   '11001': '法',
//   '00000': '打',
//   '00001': '首',
//   '00010': '发',
//   '00011': '的',
//   '001': 'l',
//   '010': 'k',
//   '011': 'd' }

// { '1000': '发',
//   '1001': '的',
//   '1010': '说',
//   '1011': '法',
//   '1100': 'j',
//   '1101': 'l',
//   '1110': 'k',
//   '1111': 'd',
//   '000': 'a',
//   '001': 's',
//   '010': 'f',
//   '0110': '打',
//   '0111': '首' }
function bin2Hex(binStr) {
    var a = 0;
    var b = -1;
    var arr = []
    var hexDic = "0123456789abcdef"
    var hexStr = "";
    binStr.split('').forEach(function (element) {
        if (element) {
            // console.log(element);
            if (a == 0) {
                b++;
                arr[b] = 0;
            }
            arr[b] += Math.pow(2, 7-a) * parseInt(element);
            if (a == 7) {
                var c = arr[b];
                arr[b] = hexDic[c / 16 | 0] + hexDic[c % 16];
                hexStr += arr[b];
            }
        }
        a = ++a % 8;
    }, this);
    return new Buffer(hexStr, "hex");
}
var fileHex = bin2Hex(finalStr);

fs.writeFileSync("三国志.max",fileHex);

var XfileHex = fs.readFileSync("./三国志.max");

var XfileHexBuffer = new Buffer(XfileHex);


fs.writeFileSync('1.txt', new Buffer('你好', 'utf-8'))